//revoir pb si objet niveau document.body sans limite de deplact 
//et un autre objet en position non absolute (ou relative?) --> les dimensions de document.body
// deviennent celles de cet objet et conditionnent les limites

// attention sous FireFox :
//   le traitt des evts est attach? au document 
//   on s'interesse donc ? l'attribut target pour savoir si l 'evt doit ?tre trait? 
//    --> il faut que le flag dragAndDrop soit positionn? sur les elts div html "en surface" seuls d?sign?s par l'attribut target
// reste a voir:
//  - DD avec cible(s) n'ayant pas le meme pere
//  - purge du code
//  - prise en compte du ReSize concurrent avec le DD sur 1 mme Div (cf. curseurs)
//  - apparence des curseurs a revoir en partioculier avec IE
//  - pb de zindex ; solution si il y a un fantome , il devrait etre rattach? ? document
//  - pb persistance DD si passage sur ascenceur et sortie du document (cas ou la div avec ascenceurs est siru?e ? l'extreme droite (tjrs 1 pb l extreme droite !))
//  - ajout d'1 image ? la place du curseur lors du DD
var ENREG_DD = 99;           // niveau de trace du DD = 99

//en fait inutilisable (surtout ave la version 4.1 de Moz) :
//var HDL_EVT_COMM = true;     // meme technique d'enreg des comportement pour IE et W3C (pas d'utilisation de addEventListener pour W3C)

var oDeplact= null;    // ? incorporer ds drag&drop ?


//function  DDLoadLimitsDyn (heightRef, widthRef){
function  DDLoadLimitsDyn (){
//===============================
// limites right-bottom du deplact fct? des dim d'un elt Html (en g?n?ral du parent) au moment du MouseDown
// les limites font parties des specs de cr?ation de l'objet ayant le comportement RS
  // il faut juste r??valuer leurs valeurs
  if (this.limitDeplact.bRectLim) {

    this.limitDeplact.rectLim.bottom      = eval(this.limitDeplact.rectLim.bottomSpecs);
    this.limitDeplact.rectLim.right       = eval(this.limitDeplact.rectLim.rightSpecs);
    this.limitDeplact.rectLim.top         = eval(this.limitDeplact.rectLim.topSpecs);
    traceExec('DDLoadLimitsDyn left=eval de '+this.limitDeplact.rectLim.leftSpecs,76);
    this.limitDeplact.rectLim.left        = eval(this.limitDeplact.rectLim.leftSpecs);
    
    if (this.specs.fantome) { 
         this.specs.fantome.top    = eval(this.specs.fantome.topSpec);
         this.specs.fantome.height = eval(this.specs.fantome.heightSpec);
    }
  }
/* ci dessous inutile : d?ja exprim? ds specs ? la cr?ation 
  // pas de directives sp?ciales dans les specs de cr?ation : on utilise les dimensions du parent
  else {
    var oBase = this.specs.objetADeplacer.parentNode;
   
    this.limitDeplact.rectLim.bottom      = pixHeight(oBase);  //parseInt(oBase.style.height);
    this.limitDeplact.rectLim.right       = pixWidth(oBase);    //parseInt(oBase.style.width);
    this.limitDeplact.rectLim.top         = 0;  
    this.limitDeplact.rectLim.left        = 0;
  }
*/
}

function  DDLoadSpecs (specs){
//===========================
// limitDeplact =
//    {  mobilite    : DragAndDrop / ReSize,      type de mobilite
//       majDyn      : true / false               dim bottom-right des limites / parent calcul?es dyn lors du MouseDown
//       orientation : h,v,2D,                    orientation autoris?e du mouvement
//       posRelI     : { top: , left}             position initiale / parent
//       bRectLim    : true / false               pr?sence d 1 rect limitant et pas de calcul dyn du rectLim
//       rectLimit   : {                          coordonn?es / parent du cadre limitant le mouvement (deplacement ou redimensionnenement)
//                       top:
//                       left:
//                       bottom:
//                       right:}
//       cibleEvt    :  target / targetAndCo      cible autoris?e pour d?clencher le mvt : ?tendue ou non ? la descendance de l'oHtml
//                                                ayant le comportement DD
//       circulaire  : true /false                le d?placement est circulaire / cadre limite --> arriver en bas le d?plact se poursuit en haut
//     }
// qq valeurs par d?faut:
//   cibleEvt :  this
//   objADeplacer : this
//   objEnDeplact : obj local si actionDirecteMm == 'aucune'
//                    objADeplacer sinon

 this.specs = new Object;

if (! specs)
  specs = new Object;

//--- cibles potentielles
 if (!specs.objetCibleEvt){
   this.specs.objetCibleEvt = new Array;
   this.specs.objetCibleEvt[0] = this;
 }
 else
 if (! (specs.objetCibleEvt instanceof Array)){
   var wObjetCibleEvt = specs.objetCibleEvt;
   this.specs.objetCibleEvt = new Array;
   this.specs.objetCibleEvt[0] = wObjetCibleEvt;
 }
 else
 if (specs.objetCibleEvt instanceof Array){
   this.specs.objetCibleEvt = specs.objetCibleEvt;
 }
 else{
   traceExec('pb def cible DD',76);
 }

// a voir eventuellement --- limitations internes aux cibles potentielles (notion de marge)
// for (var i=0; i <this.specs.objetCibleEvt; i++){
//  if (this.specs.objetCibleEvt[i].exclusionMarge)
//  ...
//}

//--- objet Html ? deplacer in fine
 this.specs.objetADeplacer = specs.objetADeplacer ?  specs.objetADeplacer : this;


//--- apparence du d?placement

//--- deplacement effectif de l'objet (objetEnDeplact) pdt mouse move
// (ne concerne que l'action directe il peut y avoir une action induite par appel de synchro)
 if (   (!specs.actionDirecteMm)      // facilite si type fantome defini --> actionDirecteMm de type fantome
     && (specs.fantome))
     specs.actionDirecteMm = 'fantome';

this.specs.actionDirecteMm    = (specs.actionDirecteMm != null)    ?  specs.actionDirecteMm         : 'deplactDirect';

this.specs.fantome = new Object;
if (this.specs.actionDirecteMm == 'fantome') {
  if  (specs.fantome) {
     this.specs.fantome.aspect = specs.fantome.aspect || 'cadre';
     this.specs.fantome.height = specs.fantome.height ? specs.fantome.height
                                                        : pixHeight(this.specs.objetADeplacer);
     this.specs.fantome.top = specs.fantome.top ? specs.fantome.top 
                                                : 0; 

  }
  else {
      this.specs.fantome.aspect = 'cadre';
      this.specs.fantome.height = pixHeight(this.specs.objetADeplacer); 
      this.specs.fantome.top = 0; 

  }
}
else
      this.specs.fantome = false;

this.specs.actionMup    = (specs.actionMup != null)    ?  specs.actionMup  : true;

this.specs.ciblesDrop   = (specs.ciblesDrop != null) ? specs.ciblesdrop :  false;

  this.specs.posRelI = new Object;
  if ( specs.posRelI){
    this.specs.posRelI.top       = specs.posRelI.top ;
    this.specs.posRelI.left      = specs.posRelI.left;
  }

//--- modif apparence du curseur
  this.specs.modCurs = new Object;
  if (specs.modCursor){
    this.specs.modCurs.avantDD   = (specs.modCursor.avantDD != 'undefined')   ? specs.modCursor.avantDD    : true;
    this.specs.modCurs.auClic = (specs.modCursor.auClic != 'undefined') ? specs.modCursor.auClic  : true;
  }
  else {
    this.specs.modCurs.avantDD   = true;
    this.specs.modCurs.auClic = true;
  }

//--- grille magnetique
   if (specs.grilleMagnetic){
      this.specs.magnet = new Object;
      this.specs.magnet.widthCol = specs.grilleMagnetic.widthCol  || 10;
      this.specs.magnet.heightRow = specs.grilleMagnetic.heightRow || 10;
   }

this.complementProp = specs.complementProp;

this.limitDeplact = new Object;
//--- circularite du deplacement
 this.limitDeplact.circulaire  = specs.circulaire || false;

//--- orientation du deplact
 this.limitDeplact.orientation  = specs.orientation ? specs.orientation : '2D';

  this.limitDeplact.bRectLim = (specs.bRectLim != null) ? specs.bRectLim :  true;

this.limitDeplact.rectLim = new Object;
 if (!specs.rectLim) 
     specs.rectLim = new Object;
 else
     this.limitDeplact.bRectLim = true;

 // maj DYnamique de bottom et/ou right
 this.specs.majDyn         = (specs.majDyn != null)    ?  specs.majDyn         : true;

if  (this.specs.majDyn) {
   this.specs.fantome.heightSpec = this.specs.fantome.height;
   this.specs.fantome.topSpec = this.specs.fantome.top;
}
if    (   (this.limitDeplact.orientation == 'h')
         ||(this.limitDeplact.orientation == '2D')){
   if  (!this.specs.majDyn) {
     this.limitDeplact.rectLim.right = eval(specs.rectLim.right) || pixWidth(this.specs.objetADeplacer.parentNode);
     this.limitDeplact.rectLim.left        =  eval(specs.rectLim.left)       || 0;
   }
   else {
     this.limitDeplact.rectLim.rightSpecs = specs.rectLim.right 
//                                || 'pixWidth(this.specs.objetADeplacer.parentNode)';
                                || 'this.specs.objetADeplacer.parentNode.offsetWidth';
     this.limitDeplact.rectLim.leftSpecs  = specs.rectLim.left  || 0;
   }
 }

 if    (   (this.limitDeplact.orientation == 'v')
          ||(this.limitDeplact.orientation == '2D')){
   if (!this.specs.majDyn) {
     this.limitDeplact.rectLim.bottom = eval(specs.rectLim.bottom) || pixHeight(this.specs.objetADeplacer.parentNode);
     this.limitDeplact.rectLim.top    = eval(specs.rectLim.top)    || 0;
   }
   else{
     this.limitDeplact.rectLim.bottomSpecs = specs.rectLim.bottom 
//                               || 'pixHeight(this.specs.objetADeplacer.parentNode)';
                               || 'this.specs.objetADeplacer.parentNode.offsetHeight';
     this.limitDeplact.rectLim.topSpecs    = specs.rectLim.top    || 0;
   }
 }
// deplacement circonscrit ? un rectangle dont les coordonn?es sont relatives au aprent de l'objet a deplacer in fine'
// --> n?cessite le chargement pr?alable ds la page de ces objets (sinon param?trer le DD avec majDyn = true)


    // annulation des dimensions inutiles des limites de deplact / orientation
    if (this.limitDeplact.orientation == 'h'){
      this.limitDeplact.rectLim.top   = this.limitDeplact.rectLim.bottom = null;  // top et bottom contraints par orientation + posRelI
    }
    else
    if (this.limitDeplact.orientation == 'v')
      this.limitDeplact.rectLim.left  = this.limitDeplact.rectLim.right = null;   // left et right contraints par orientation + posRelI

  // positionnement initial de l'objet mobile
  if (this.specs.posRelI.top != null)
    this.specs.objetADeplacer.style.top  = this.specs.posRelI.top;
  if (this.specs.posRelI.left != null)
    this.specs.objetADeplacer.style.left = this.specs.posRelI.left;
}




//_________________________________________________________________________________________________________________________________

function DragAndDrop(specs)
//=========================
//        specs = {  orientation: <o>,
//                   posRelI     : <p>,
//                   rectLim    : {top, left, bottom, right
//                   circulaire     : <boolean>}
{
/*
  var orientation = (specs && (specs.orientation)) ?  ((specs.orientation =='h') ? 'deplactHorizontal'
                                                                                  :(specs.orientation =='v') ? 'deplactVertical'
                                                                                                             : '2D')
                                                    : null;

*/
          // cr?ation de l'attribut de l'oCiu stockant les infos relatives au DD
          if (!this.oCiu) this.oCiu = new Array();
              this.oCiu['DragAndDrop'] = this;

          // chargement des sp?cifications du d?placement
          // r?f?rence aux m?thodes de chargt par d?faut en absence de m?thodes sp?cifiques ? l'oCiu
          if (!this.oCiu['DragAndDrop'].loadSpecs){
             this.oCiu['DragAndDrop'].loadSpecs = DDLoadSpecs;
          }
          // chargement des limites non dynamiques   (dynamiques cf. mouseDown)
          this.oCiu['DragAndDrop'].loadSpecs(specs);

          // pour le chargt dynamique, r?f?rence ? la m?thode dynamique standart
          if (this.oCiu['DragAndDrop'].specs.majDyn) {
              if (!this.oCiu['DragAndDrop'].loadLimitsDyn)
                this.oCiu['DragAndDrop'].loadLimitsDyn = DDLoadLimitsDyn;
              // chargement des limites dynamiques   (cf. ?galt mouseDown)
              this.oCiu['DragAndDrop'].loadLimitsDyn();//this.oCiu['DragAndDrop'].specs.objetADeplacer.parentNode);
          }


          // pour W3C Mozilla : DD est enregistr? et donc pris en compte au niveau du document il faut donc marqu?
          // sp?cifiquement les elts Html sensibles au DD
//          this.dragAndDrop = true;
          // marquage des elts Html poign?es pour le DD, lien entre ces objets et les specs du DD
          // cibles d?sign?es
             var oCiu = this.oCiu['DragAndDrop'];
             for (var i=0; i < oCiu.specs.objetCibleEvt.length; i++) {
                 oCiu.specs.objetCibleEvt[i].dragAndDrop = true;
                 oCiu.specs.objetCibleEvt[i].refObjSpecs = this;
             }

          // enregistrement comportement DD pour navigateur IE
          //(pas d'utilisation de attachEvent qui rend this indisponible -> utilisation d'1 m?thode maison addHandler)
          if ( typeof document.addEventListener == "undefined"){

                 // enregistrement du MDown
                 var tOCible =  oCiu.specs.objetCibleEvt;

                 for (var i=0; i < tOCible.length; i++) {
                   tOCible[i].addHandler = addHandler;
                   tOCible[i].methodMouseDown = DragAndDropMouseDownHandler;
                   tOCible[i].addHandler(tOCible[i],'onmousedown','methodMouseDown');

                   tOCible[i].methodMouseMove = DragAndDropMouseMoveHandler;
                   tOCible[i].methodMouseUp   = DragAndDropMouseUpHandler;
                   tOCible[i].addHandler(tOCible[i],'onmousemove','methodMouseMove');
                   tOCible[i].addHandler(tOCible[i],'onmouseup','methodMouseUp');

                   // pour test
                   tOCible[i].methodDebDD   = function (){window.status ='debut du d?placement this.id='+this.id;};
                   tOCible[i].addHandler(tOCible[i],'onmousedown','methodDebDD');
                   tOCible[i].methodFinDD   = function (){window.status ='fin du d?placement';};
                   tOCible[i].addHandler(tOCible[i],'onmouseup','methodFinDD');
                 }

//              this.onmousedown = DragAndDropMouseDownHandler;
//              this.onmousemove = DragAndDropMouseMoveHandler;
//              this.onmouseup   = DragAndDropMouseUpHandler;
          }

          // enregistrement W3C
          else{
              if (!document.enregtDragAndDrop){
                 document.enregtDragAndDrop = true;
                 document.addEventListener("mousemove",DragAndDropMouseMoveHandler, false);
                 document.addEventListener("mouseup",  DragAndDropMouseUpHandler, false);
                 document.addEventListener("mousedown",StopSelectDef,false);
                 document.addEventListener("mousedown",DragAndDropMouseDownHandler, false);
           }
          }



// (cr?ation et) positionnement initial du fantome
// pour acc?l?rer le processus 
              var objetADeplacer =  this.specs.objetADeplacer;

                //  soit un cadre fantome mobile
                if (this.specs.fantome){
                  var cadreFantome = rialto.session.objects ? rialto.session.objects['cadreFantomeUnique']:null; //document.getElementById('cadreFantomeUnique');
                  if (cadreFantome == null) {
                    rialto.session.objects['cadreFantomeUnique'] = cadreFantome = document.createElement('DIV');
                    cadreFantome.id = 'cadreFantomeUnique';
                    cadreFantome.className = 'fantomeDD_' + this.specs.fantome.aspect;
                    objetADeplacer.parentNode.appendChild(cadreFantome);
                  }
                 }
} // fin du constructeur
 
        StopSelectDef = function(e){
                 stopDefault(e);
        }

        DragAndDrop.cibleOuFilsCible = function (oHtml) {
        //------------------------------------------
            var div= oHtml;
            while (div && !div.dragAndDrop) {
              div = div.parentNode;
            }
            if (div && div.dragAndDrop) {
              return div;
            }  
            else
              return null;
        }
    
        DragAndDropMouseDownHandler= function (e){
        //----------------------------------------

                if (!e) var e = window.event;

                // restriction ? la zone sensible au DD ? l'elt Html enregistrant l evt
                var oSourceEvt = e.target ? e.target: e.srcElement;
                // mod pour Moz si clic non direct sur elt avec attribut .dragAndDrop mais fils
                var cibl = DragAndDrop.cibleOuFilsCible(oSourceEvt); // 
                if (!cibl){
                   return ;
                }
                else{
                   oSourceEvt = cibl;  // mod pour Moz si clic non direct sur elt avec attribut .dragAndDrop mais fils
                }

                 var oHtml = oSourceEvt;
                // blocage du redimebsionnement
/*                if (oHtml.oCiu['ReSize']){
                   oHtml.oCiu['ReSize'].svgReSize = oHtml.oCiu['ReSize'].reSize;
                   oHtml.oCiu['ReSize'].reSize = false;
                   //traceAct2('blocage ReSize');
                }
*/

                // objet detenant les specs du DD
                var oSpecs = oHtml.refObjSpecs;

                // zone d'exclusion / dragAndDrop'
                var direction =  DirDeplact(oHtml,e, pixHeight(oHtml),pixWidth(oHtml)
                                           , oHtml.margeSensible,true
                                           ,oSpecs.limitDeplact.orientation);
               if (! direction)  {
                   return;
               }

                // chargement des limites s'il y a lieu
                if (oSpecs.specs.majDyn)
                   oSpecs.loadLimitsDyn(oSpecs.specs.objetADeplacer.parentNode);
                // objet Html ? deplacer in fine
                var objetADeplacer =  oSpecs.specs.objetADeplacer;

                // objet Html en deplact pdt le DD
                //  soit un cadre fantome mobile
                if (oSpecs.specs.fantome){
                  var cadreFantome = document.getElementById('cadreFantomeUnique');
                  if (cadreFantome == null) {
                    cadreFantome = document.createElement('DIV');
                    cadreFantome.id = 'cadreFantomeUnique';
                    cadreFantome.className = 'fantomeDD_' + oSpecs.specs.fantome.aspect; //'cadreDeplactFenetreMobile';
                    objetADeplacer.parentNode.appendChild(cadreFantome);
                  }
                  else
                  if (cadreFantome.parentNode != objetADeplacer.parentNode) {
                    cadreFantome.className = 'fantomeDD_' + oSpecs.specs.fantome.aspect; //'cadreDeplactFenetreMobile';
                    objetADeplacer.parentNode.appendChild(cadreFantome);
                  }

                  cadreFantome.style.zIndex = 100000;
                  // objetADeplacer peut etre de type inline d'ou offsetTopLeft (ss compter que au Md 
                  // l'objet est forcement charg? ds le DOM il n'y a donc pas de restriction ? lusage d offset
               //   alert('MD oSpecs.specs.fantome.top= '+oSpecs.specs.fantome.top);
                  if (!oSpecs.specs.majDyn)
                     cadreFantome.style.top    = objetADeplacer.offsetTop; // pixTop(objetADeplacer);
                  else
                      cadreFantome.style.top = objetADeplacer.offsetTop + oSpecs.specs.fantome.top; 
                      
                  cadreFantome.style.left   = objetADeplacer.offsetLeft; //pixLeft(objetADeplacer);
                  cadreFantome.style.width  = pixWidth(objetADeplacer);

                      // sous Moz la bordure n est pas compt?e ds width il faut la soustraire pour ne pas provoquer d ascenceur
                      // ds la div container de fantome
                      // sous IE c est inutile la bordure etant comprise ds width , mais comme borderTopWidth n existe pas sous IE
                      // et que l argt '0' permet ? getComputStyle de ramener 0 l appel peut se faire ss dommage mm ds ce cadre
                  var topWidthBord = getComputStyle(cadreFantome,'borderTopWidth','0');
                  var bottomWidthBord = getComputStyle(cadreFantome,'borderBottomWidth','0');
                  if (  topWidthBord  || topWidthBord){
                      var bWidth =     topWidthBord  + bottomWidthBord;
                      cadreFantome.style.width = parseInt(cadreFantome.style.width) - bWidth;
                  }
/* ou bien :
                  if (getComputStyleStr(cadreFantome,'borderStyle') != 'none'){
                      var bWidth =         getComputStyle(cadreFantome,'borderTopWidth','0')
                                       +   getComputStyle(cadreFantome,'borderBottomWidth','0');
                      cadreFantome.style.width = parseInt(cadreFantome.style.width) - bWidth;
                  }
*/
                  cadreFantome.style.height = oSpecs.specs.fantome.height; // pixHeight(objetADeplacer);
//                  cadreFantome.style.visibility = 'visible';
                  cadreFantome.style.display  = 'block';

                  var objetEnDeplact = cadreFantome;
                  objetEnDeplact.refObjSpecs = oSpecs;  // pour Moz en mode fantome

                  var top = parseInt(cadreFantome.style.top); //objetEnDeplact.offsetTop; //pixTop(objetEnDeplact);
                  var left = parseInt(cadreFantome.style.left); //objetEnDeplact.offsetLeft; //pixLeft(objetEnDeplact);


                }
                // soit directement l element ? deplacer
                else{
                  if (oSpecs.specs.actionDirecteMm == 'deplactDirect'){
                     var objetEnDeplact = objetADeplacer;
                     var top = pixTop(objetEnDeplact);
                     var left = pixLeft(objetEnDeplact);
                  }
                  // soit aucun objet deplac? directement
                  else {
                     var top = pixTop(objetADeplacer);
                     var left = pixLeft(objetADeplacer);
                     var objetEnDeplact = new Object;
                     objetEnDeplact.style = new Object;
                     objetEnDeplact.style.top = top;
                     objetEnDeplact.style.left = left;
                   }
                }


                  // test pour insertion d'1 icone lors du deplact : a revoir
/*
                    iconDeplact    = document.createElement('DIV');
                    iconDeplact.id = 'iconDeplact';
                    iconDeplact.className  = 'btonFenFermOn';
                    traceExec('e.clientY= '+e.clientY,61);
                    traceExec('e.clientX= '+e.clientX,61);
                    traceExec('e.layerY= '+e.layerY,61);
                    traceExec('e.layerX= '+e.layerX,61);
                    traceExec('top= ' +top,61);
                    traceExec('left= '+left,61);
                    iconDeplact.style.position = 'absolute';
                    // pour Moz utiliser e.layerX/Y (qui donne la position ds la tirette) + position tirette ds objetEnDeplact
                    // sinon en  pr?sence d'ascenceur e.clientY est faux
                    iconDeplact.style.top  = e.clientY - top - 10;
                    iconDeplact.style.left = e.clientX - left - 10;
//                    objetEnDeplact.style.cursor = 'move';
                    objetEnDeplact.style.cursor = 'crosshair';
                    objetEnDeplact.appendChild(iconDeplact);
*/
                oDeplact = {oThis          : oSpecs,
                            oSource        : oHtml,
                            fantome        : oSpecs.specs.fantome,
                            objetEnDeplact : objetEnDeplact,
                            objetADeplacer : objetADeplacer,

                            actionMup  : oSpecs.specs.actionMup,

                            tx             : e.clientX - left,
                            ty             : e.clientY - top,
                            // positions initiales de l'objet ? d?placer au mouse down.  (pour synchro)
                            posInitObjADeplacer : {top : pixTop  (objetADeplacer),
                                                   left: pixLeft (objetADeplacer)} ,
                            // position initiales au mouse down
                            topI           : top,
                            leftI           :left,
                            // positions au fur et ? mesure des mouse move (initialement = position au )mouse down). (pour synchro)
                            prevTop        : top,
                            prevLeft       : left,
                            // temoin d un deplacement de la souris (= mouse move effectif)
                            mvtEffectif     : false,
                            // temoin (s'il y a des cibles definies) d'un bon positionnement / cibles
                            cibleOk        : false

                            };
                if ( this.setCapture) {
                   this.setCapture();
//pour permettre par exemple ? la fenetre d etre activ?e par un Md ds barre Titre pour DD stopEvent(e);
                   if (   (!oSpecs.specs.modCurs.avantDD)
                       && (oSpecs.specs.modCurs.auClic)) {
                      DragAndDrop.modCurseur(oHtml,direction,oSpecs.limitDeplact.orientation,false);
                   }
                }
                else {
                   if (   (!oSpecs.specs.modCurs.avantDD)
                       && (oSpecs.specs.modCurs.auClic)) {
                    if (oSpecs.specs.fantome)
                         DragAndDrop.modCurseur(objetEnDeplact,direction,oSpecs.limitDeplact.orientation,true);
                    else
                         DragAndDrop.modCurseur(oHtml,direction,oSpecs.limitDeplact.orientation,true);
                   }
                }
        // essentiellement pour les pb issu du traitement centralis? sur obj doct pour FireFox
        var oThis = oDeplact.oThis;
        if (oThis.afterMD){
            oThis.afterMD();
        }

//              stopEvent();
        }


          DragAndDropMouseMoveHandler = function (e){
         //----------------------------------
 // tester la sortie du navigateur pour realiser oDeplact = null juste avant ?

            if (!e) var e = window.event;

            oCible = e.target        ? e.target        : e.srcElement;
/* supp prov
            if (! oCible.dragAndDrop) return;  // ne fctionne pas bien avec IE : perte si deplact rapide
                                               // fctionne avec Mozilla sauf si cible = fils auquel cas cela ne fctionne jamais bien
                                               //   avec ou sans cette intruction
*/
               oHtml = this;

            // DD non amorc? ; materialisation de la zone active par chgt d'apparence du curseur
            var oHtml = e.target        ? e.target        : e.srcElement;
            
            if (!oDeplact) {
              if (!oHtml.dragAndDrop) {

              
                   // a revoir
                  //necessaire si cette Div fille n'a pas de curseur explicitement d?fini pour ne pas se voir attribu? le curseur
                  //de la Div (cible du DD) sous-jacente si l'on est deja pass? directement dessus
                  //oHtml.style.cursor = "default";
                 return;
              }

/* supp prov
                       if (oHtml.oCiu['ReSize']  && oHtml.oCiu['ReSize'].dsChampMm){
                         oHtml.oCiu['ReSize'].dsChampMm = false;
                         return;
                       }
*/
//                       oHtml.svgCursor = oHtml.style.cursor;
                       // objet detenant les specs du DD
                       var oSpecs = oHtml.refObjSpecs;

                       if (oSpecs.specs.modCurs.avantDD){

                         var direction = DirDeplact(oHtml,e,
                                                        pixHeight(oHtml),pixWidth(oHtml)
                                                       , oHtml.margeSensible, true
                                                       ,oSpecs.limitDeplact.orientation);
                         DragAndDrop.modCurseur(oHtml,direction,oSpecs.limitDeplact.orientation,false);

                       }

              }
              // DD en cours
              else {
                     if (e.clientX >= 0 && e.clientY >= 0){

                        var   posObjEnDeplact = oDeplact.objetEnDeplact.style;
                        oDeplact.mvtEffectif = true;

                        // positionnement sans contrainte
                        posObjEnDeplact.left = e.clientX - oDeplact.tx;
                        posObjEnDeplact.top  = e.clientY - oDeplact.ty;
// supp  prov
                        // application des contraintes
                // objet detenant les specs du DD
                        var oThis = oDeplact.oThis;

                   if (oThis.limitDeplact.bRectLim) {
                        if (oThis.limitDeplact.orientation =='v'){
// a restreindre / existence autre curseur sur mm obj mobile
                            posObjEnDeplact.left =   oDeplact.leftI;
                            // contrainte top - bottom
                            if (parseInt(posObjEnDeplact.top) < parseInt(oThis.limitDeplact.rectLim.top))
                                posObjEnDeplact.top =
                                         oThis.limitDeplact.circulaire ? (oThis.limitDeplact.rectLim.bottom
                                                                             -parseInt(posObjEnDeplact.height))
                                                                           : oThis.limitDeplact.rectLim.top;

                            if (   (   parseInt(posObjEnDeplact.top)
                                     + parseInt(oDeplact.objetEnDeplact.offsetHeight) )
                                 > parseInt(oThis.limitDeplact.rectLim.bottom))

                                posObjEnDeplact.top =
                                         oThis.limitDeplact.circulaire ? oThis.limitDeplact.rectLim.top
                                                                           :(oThis.limitDeplact.rectLim.bottom
                                                                            -parseInt(oDeplact.objetEnDeplact.offsetHeight));
                        }   // 'v'

                        if (oThis.limitDeplact.orientation =='h'){
// a restreindre / existence autre curseur sur mm obj mobile
                            posObjEnDeplact.top  =  oDeplact.topI;
                            // contrainte left - right
                            if (parseInt(posObjEnDeplact.left) < parseInt(oThis.limitDeplact.rectLim.left)){
                               posObjEnDeplact.left =
                                          oThis.limitDeplact.circulaire ? (  parseInt(oThis.limitDeplact.rectLim.right)
                                                                     - parseInt(posObjEnDeplact.width))
                                                                            : parseInt(oThis.limitDeplact.rectLim.left);
                            }
                            else
                            if (   (   parseInt(posObjEnDeplact.left)
                                     + parseInt(posObjEnDeplact.width) )
                                 > parseInt(oThis.limitDeplact.rectLim.right)) {
                                 posObjEnDeplact.left =
                                    oThis.limitDeplact.circulaire ?  parseInt(oThis.limitDeplact.rectLim.left)
                                                                  : (  parseInt(oThis.limitDeplact.rectLim.right)
                                                                     - parseInt(posObjEnDeplact.width));
                            }
                        }  // 'h'

                        if (oThis.limitDeplact.orientation =='2D'){
                            // contrainte top - bottom
                            if (parseInt(posObjEnDeplact.top) < oThis.limitDeplact.rectLim.top){
                                posObjEnDeplact.top = oThis.limitDeplact.rectLim.top;
                            }
                            else
                            if (     oThis.limitDeplact.rectLim.bottom   // ssi limite vers  bas
                                &&  (
                                      (   parseInt(posObjEnDeplact.top)
                                        + parseInt(posObjEnDeplact.height) )
                                    > oThis.limitDeplact.rectLim.bottom)
                                )
                                posObjEnDeplact.top = (  oThis.limitDeplact.rectLim.bottom
                                                                     - parseInt(posObjEnDeplact.height));

                            // contrainte left - right
                            if (parseInt(posObjEnDeplact.left) < oThis.limitDeplact.rectLim.left)
                                posObjEnDeplact.left = oThis.limitDeplact.rectLim.left;
                            else
                            if (     oThis.limitDeplact.rectLim.right            // ssi limite droite
                                &&   (
                                      (   parseInt(posObjEnDeplact.left)
                                        + parseInt(posObjEnDeplact.width) )
                                      > oThis.limitDeplact.rectLim.right)
                                )

                                posObjEnDeplact.left = ( oThis.limitDeplact.rectLim.right
                                                                     - parseInt(posObjEnDeplact.width));

                        } // 2D

                    } // bRectLim

                        // effet grille magnetique
                        if (oThis.specs.magnet){
                                posObjEnDeplact.top =
                                      Math.round(parseInt(posObjEnDeplact.top) / oThis.specs.magnet.heightRow)
                                    * oThis.specs.magnet.heightRow;
                                posObjEnDeplact.left =
                                      Math.round(parseInt(posObjEnDeplact.left) / oThis.specs.magnet.widthCol)
                                    * oThis.specs.magnet.widthCol;
                        }

                        // position /cibles autoris?es
                        if (    (oThis.specs.ciblesDrop)
                            &&  (!oThis.specs.cibleOk)) {
                          for (var i in oThis.specs.ciblesDrop){  // sortie forcee de bcle si cible convient
                            var cible = oThis.specs.ciblesDrop[i];
                            // ne fonctionne que si le projectile et la cible ont m?me r?f?rent pour leurs positions top et left
                            // a revoir
                            // calcul des dim de cible dynamique : ? d?porter eventuellet ds MouseDown
                            if (     (parseInt(posObjEnDeplact.left) >= pixLeft(cible)   )
                                 &&  (parseInt(posObjEnDeplact.top ) >= pixTop(cible)    )
                                 && (     (  parseInt(posObjEnDeplact.left) + parseInt(posObjEnDeplact.width) )
                                      <=  (  pixLeft(cible)                 + pixWidth(cible)                 ))
                                 && (     (  parseInt(posObjEnDeplact.top)  + parseInt(posObjEnDeplact.height) )
                                      <=  (  pixTop(cible)                  + pixHeight(cible)                ))
                                ) {

                                         oDeplact.cibleOk = true;

                                         break;

                            }    // test 1 cible
                            else {
                                         oDeplact.cibleOk = false;
                            }
                          }   // for

                          DragAndDrop.modCurseur(oDeplact.objetEnDeplact,oThis.limitDeplact.orientation,oDeplact.orientation,oDeplact.cibleOk);
                        } //cibles

                        if (oThis.synchro){
                           // calcul des variations  (seult si pseudo fct callback)

                           //--- calcul des deplacts depuis le Mouse Down

                           // deplact indirect
                           if (oDeplact.objetADeplacer != oDeplact.objetEnDeplact) {
                              var totDeltaTop =    parseInt(posObjEnDeplact.top)
                                                 - parseInt(oDeplact.objetADeplacer.style.top) ;
                              var totDeltaLeft =   parseInt(posObjEnDeplact.left)
                                                 - parseInt(oDeplact.objetADeplacer.style.left);
                            }

                            // deplact direct : ref aux dims initiales
                            else{
                              var totDeltaTop =    parseInt(posObjEnDeplact.top)
                                                 - parseInt(oDeplact.topI);
                              var totDeltaLeft =   parseInt(posObjEnDeplact.left)
                                                 - parseInt(oDeplact.leftI);
                            }

                           //--- calcul des deplacts depuis le dernier Mouse move
                           var deltaTop =    parseInt(posObjEnDeplact.top)
                                                 - parseInt(oDeplact.prevTop) ;
                           var deltaLeft =   parseInt(posObjEnDeplact.left)
                                                 - parseInt(oDeplact.prevLeft);

                           //--- Sauvegarde des positions
                           oDeplact.prevTop  = parseInt(posObjEnDeplact.top);
                           oDeplact.prevLeft = parseInt(posObjEnDeplact.left);


                          // alert('DD Mm synchro = '+oThis.synchro);
                           oThis.synchro(   {top: totDeltaTop, left: totDeltaLeft}                 // deplact total   depuis Md
                                          , {top:deltaTop,     left: deltaLeft}                    // deplact relatif depuis Mm
                                          , {}                                                     // poistions initiales au Md
                                         );

                        }        // synchro

                     } //e.client

                 }  // DD en cours
                 stopEvent(e);
         };

         DragAndDropMouseUpHandler = function (e){
         //--------------------------------
               if (!e) var e = window.event;
               // objet en deplacement
               if (oDeplact && oDeplact.objetEnDeplact){
               
               
               


                   // modele IE
                   if ( this.releaseCapture){
                     if (   (!oDeplact.oThis.specs.modCurs.avantDD)
                        && (oDeplact.oThis.specs.modCurs.auClic)) {
                          this.style.cursor = 'default';
                     }
                     this.releaseCapture();
                   }

                   // modele W3C Moz
                   else{
                     if (oDeplact.fantome)
                       oDeplact.objetEnDeplact.style.cursor = 'default';
                     else
                       oDeplact.oSource.style.cursor = 'default';
                   }
                   // deblocaga ReDim
                   //if (oHtml.oCiu['ReSize']) oHtml.oCiu['ReSize'].reSize = oHtml.oCiu['ReSize'].svgReSize;
                   var  oHtml = oDeplact.objetEnDeplact;
                   oHtml.reSize = oHtml.svgReSize;

                   var oThis = oDeplact.oThis;
                   
                   // compute delta 
                    //--- calcul des deplacts depuis le Mouse Down et deplact effectif si besoin

                       // deplact indirect
                       if (oDeplact.objetADeplacer != oDeplact.objetEnDeplact) {
                            var totDeltaTop =    parseInt(oDeplact.objetEnDeplact.style.top)
                                                 - parseInt(oDeplact.objetADeplacer.offsetTop) ;
                            var totDeltaLeft =   parseInt(oDeplact.objetEnDeplact.style.left)
                                                - parseInt(oDeplact.objetADeplacer.offsetLeft);



                            // deplacement effectif de l'objet a deplacer
//                           oDeplact.objetADeplacer.style.top = oDeplact.objetEnDeplact.style.top;
//                           oDeplact.objetADeplacer.style.left = oDeplact.objetEnDeplact.style.left;
                        }

                        // deplact direct : ref aux dims initiales
                        else{
                          var totDeltaTop =    parseInt(oDeplact.objetEnDeplact.style.top)
                                             - parseInt(oDeplact.topI);
                          var totDeltaLeft =   parseInt(oDeplact.objetEnDeplact.style.left)
                                             - parseInt(oDeplact.leftI);
                        }
                   
               
                   // deplacement effectif ? r?aliser
                   if (oDeplact.actionMup){

                     // verification de la position /cibles autoris?es
                     if (   (!oThis.specs.ciblesDrop)
                         || (oDeplact.cibleOk)) {

                           //--- calcul des deplacts depuis le Mouse Down et deplact effectif si besoin

                           // deplact indirect
                           if (oDeplact.objetADeplacer != oDeplact.objetEnDeplact) {
/*                                var totDeltaTop =    parseInt(oDeplact.objetEnDeplact.style.top)
                                                     - parseInt(oDeplact.objetADeplacer.offsetTop) ;
                                var totDeltaLeft =   parseInt(oDeplact.objetEnDeplact.style.left)
                                                    - parseInt(oDeplact.objetADeplacer.offsetLeft);

*/

                                // deplacement effectif de l'objet a deplacer
                               oDeplact.objetADeplacer.style.top = oDeplact.objetEnDeplact.style.top;
                               oDeplact.objetADeplacer.style.left = oDeplact.objetEnDeplact.style.left;
                            }

                            // deplact direct : ref aux dims initiales
                            else{
/*                              var totDeltaTop =    parseInt(oDeplact.objetEnDeplact.style.top)
                                                 - parseInt(oDeplact.topI);
                              var totDeltaLeft =   parseInt(oDeplact.objetEnDeplact.style.left)
                                                 - parseInt(oDeplact.leftI);
*/
                            }
                            
                            if (oThis.synchroDDMup) {
                                
                                oThis.synchroDDMup(   {top: totDeltaTop, left: totDeltaLeft}                 // deplact total   depuis Md
                                                , {}                                                     // positions initiales au Md
                                         );
                            }
                    }
                   }

                   // masque fantome eventuel
                   if (oDeplact.fantome)
//                     oDeplact.objetEnDeplact.style.visibility = 'hidden';
                     oDeplact.objetEnDeplact.style.display = 'none';


                   // declencht de traitements cod?s dans l'objet ayant re?u le comportement DD
                   // mvt effectif
                   if (oDeplact.mvtEffectif) {
                     if (oThis.afterDD)
                       oThis.afterDD(totDeltaTop,totDeltaLeft);
                   }
                   // seult un clic r?alis? : pas de mvt
                   else{
                   if (oThis.afterClic)
                     oThis.afterClic();
                   }


                   oDeplact = null;

                   stopEvent(e);
               }
          }

DragAndDrop.modCurseur = function (oHtml, direction, orientation, cible){
//=======================================
                         if (cible){
                            oHtml.style.cursor = "move";  // a revoir  pour Moz pour les fenetres
                                                          // ne fonctionne pas il doit falloir changer le curseur d'1 autre elt
                            return;
                         }

                         if (direction == ""){
// ne fctionne pas le curseur peut correspondre au passage precdt ds la zone sensible
//                            oHtml.style.cursor = oHtml.svgCursor;
                            oHtml.style.cursor = "default";
//                            oHtml.oCiu['DragAndDrop'].dsChampMm = false;
                         }
                         else
                         if (orientation == 'v')         //oSpecs.limitDeplact.
                           {oHtml.style.cursor = direction + "-resize";
                            traceExec('DD mm ds champ dir='+direction,76);
//                            oHtml.oCiu['DragAndDrop'].dsChampMm = true;
                         }

                         else
                         if (orientation == 'h'){
                           oHtml.style.cursor = direction + "-resize";
                            traceExec('DD mm ds champ dir='+direction,76);
//                            oHtml.oCiu['DragAndDrop'].dsChampMm = true;
                         }

                         else{
                           oHtml.style.cursor = 'move';
                            traceExec('DD mm ds champ dir='+direction,76);
//                            oHtml.oCiu['DragAndDrop'].dsChampMm = true;
                         }
}

DragAndDrop.release=function(domObj){
    if (domObj && domObj.specs){
        domObj.loadSpecs = null;
        domObj.objetADeplacer = null;
        if (domObj.specs.objetCibleEvt){
            for (var i=0;i<domObj.specs.objetCibleEvt.length;i++){
                domObj.specs.objetCibleEvt[i].refObjSpecs=null;
            }
            domObj.specs.objetCibleEvt=null;
        }
        domObj.specs.fantome=null;
        domObj.specs=null;
        domObj.tHandler=null;
        domObj.onmousemove=null;
        domObj.onmousedown=null;
        domObj.onmouseup=null;
        domObj.limitDeplact=null;
        domObj.addHandler=null;
        domObj.loadLimitsDyn=null;
        domObj.methodDebDD=null;
        domObj.methodFinDD=null;
        domObj.methodMouseDown=null;
        domObj.methodMouseMove=null;
        domObj.methodMouseUp=null;
    }
}